#include "proprietarygffreader.h"

ProprietaryGffReader::ProprietaryGffReader(QString gffFileName, QHash<QString, QString> clusterHashTable, QObject *parent) :
    clusterHashTable(clusterHashTable), GffReader(gffFileName, parent)
{
    qDebug() << "Proprietary gffReader created " << endl;
}

void ProprietaryGffReader::process()
{
    qDebug() << "Proprietary gffReader reading file " << gffFileName << endl;

    QFile gff(gffFileName);

    if( !gff.exists() )
    {
        qDebug() << "file not found." << endl;
        return;
    }

    if( ! gff.open(QIODevice::ReadOnly))
    {
        qDebug() << "file " << gffFileName << " can't be opened." << endl;
        return;
    }
    qDebug() << "file " << gffFileName << " opened." << endl;

    QTextStream inStream(&gff);
    QString line;
    do {
        line = inStream.readLine();
        //qDebug() << "line = " << line << endl;

        if( ! line.startsWith("#") )
        {
            //divide line into major tokens- by the tab delim
           QStringList majorTokens = line.split("\t", QString::SkipEmptyParts);
           QString seqId;
           QString source;
           QString type;
           int start;
           int stop;
           bool posStrand;
           processFirstColumnsInLine( majorTokens, seqId, source, type, start, stop, posStrand);

           //now I have all the basic info

           //let's flesh out the rest:
           QString parentContigId;
           bool hasCluster;
           QString clusterId;
           bool hasSpecies;
           QString species;
           QString uniprot = "-";//not all will have uniprot id
           QString description = "-";//not all will have a description
           QString name = "-";
           QString exp = "-";
           int perc_qry_cvrg;
           int perc_hit_cvrg;
           int perc_ident;
           processRemainingData( majorTokens, parentContigId, hasCluster, clusterId,
                                     hasSpecies, species,
                                     uniprot, description, name,
                                     perc_qry_cvrg, perc_hit_cvrg, perc_ident );

           ProprietaryGenomeElementDataPacket* p = new  ProprietaryGenomeElementDataPacket( seqId, source, type, start, stop, posStrand,
                                                                        parentContigId, hasCluster, clusterId,
                                                                        hasSpecies, species,
                                                                        uniprot, description, name,
                                                                        perc_qry_cvrg, perc_hit_cvrg, perc_ident );
           emit( dataPacketGenerated( p ) );
        }
    } while (!inStream.atEnd() );

    qDebug() << "done reading gff file " << gffFileName << endl;

    gff.close();

    emit( finished() );
}

void ProprietaryGffReader::processFirstColumnsInLine( QStringList tokens, QString& seqId, QString& source, QString& type, int& start, int& stop, bool& posStrand )
{
    //---------GET ID------------
    //NORMAL seqId position:  seqId = tokens[0];
    //ID position in this data set
    if( tokens[8].contains("ID=") )
    {
        QRegExp rx("ID=[^;]*;");//ID=any num characters execpt ; then ;
        int pos = rx.indexIn( tokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {
            seqId = list[i].remove("ID=");//.remove(".cdna;");
            //qDebug() << "------ id    " << id << endl;
        }
    }

    source = tokens[1];
    type = tokens[2];
    start = tokens[3].toInt();
    stop = tokens[4].toInt();
    //skipping score - 5th token
    QString strand = tokens[6];
    if( strand.contains("+") )
        posStrand = true;
    else
        posStrand = false;
    //skipping phase - 7th token
}

void ProprietaryGffReader::processRemainingData(QStringList& majorTokens, QString& parentContigId, bool& hasCluster, QString& clusterId,
                          bool& hasSpecies, QString& species,
                          QString& uniprot, QString& description, QString& name,
                          int& perc_qry_cvrg, int& perc_hit_cvrg, int& perc_ident )
{
    //------------------GET PARENT CONTIG ID--------------
    parentContigId = majorTokens[0]; //This is usually the seqID, but in this case it is the contig Id

    //-------------------GET CLUSTER INFO-----------------
    hasCluster = false; //generally false
    clusterId = "-";
    if( majorTokens[2].contains("mRNA")) //if mRNA- will have cluster.  Need to get cluster key.  Cluster id supplied from cdhit algorithm
    {
        hasCluster = true; //RIGHT NOW:  only mRNA's will have clusters, though technically it ought to be CDS's because faa file is used
        QString clusterKey;
        if( majorTokens[8].contains("ID=") )//This is the code to get the id- id is the cluster id
        {
            QRegExp rx("ID=[^;]*;");//ID=any num characters execpt ; then ;
            int pos = rx.indexIn( majorTokens[8]);
            QStringList list = rx.capturedTexts();
            for(int i = 0; i < list.size(); i++)
            {
                clusterKey = list[i].remove("ID=").remove(".cdna;");//only difference between clusterKey and id is removing .cdna
            }

            //use cluster id to find the cluster
            if( clusterHashTable.contains(clusterKey) )
            {
                clusterId = clusterHashTable.value(clusterKey);
            }
        }

        //qDebug() << "cluster id = " << clusterId << " cluster key = " << clusterKey;
    }
    //-------------------GET SPECIES-----------------------
    //OLD METHOD:
//    //get species, strain and contig from the first token
//    //note- may not be able to always assume that format is species_strain_contig
//    QStringList speciesStrainContig = majorTokens[0].split( "_", QString::SkipEmptyParts );
//   QString species = speciesStrainContig[0];
//    QString strain = speciesStrainContig[1];
//    QString contig =  speciesStrainContig[2];
    //NEW METHOD:  species_strain  -- later may want to separate this out, but will work for now
    hasSpecies = true;
    QStringList speciesStrainContig = majorTokens[0].split( "_", QString::SkipEmptyParts );
    species = speciesStrainContig[0].append("_").append(speciesStrainContig[1]);

    //-------------------GET UNIPROT ID----------------------
    if( majorTokens[8].contains("Note=") )
    {
        QRegExp rx("Note=[^:]*:");//Note=any num characters execpt : then :
        int pos = rx.indexIn( majorTokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {
            uniprot = list[i].remove("Note=").remove(":");
            //qDebug() << "------ uniprot    " << uniprot << endl;
        }
    }

    //-------------------GET DESCRIPTION---------------------
    if( majorTokens[8].contains("Note=") )
    {
        //QRegExp rx("Note=[^=]*n=");//Note=any num characters then n=
        QRegExp rx("Note=[^%=]*[%=]");//Note=any num characters then n=
        int pos = rx.indexIn( majorTokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {

            //QRegExp rx2(":[^=]*n=");//take first regexp, apply new pattern  : any num char n=
            QRegExp rx2(":[^%=]*[%=]");//take first regexp, apply new pattern  : any num char n=
            int pos2 = rx2.indexIn( list[i]);
            QStringList list2 = rx2.capturedTexts();
            description = list2[0].remove(":").remove("n=").remove("(/%");
            //qDebug() << "------ getting descr    " << description << endl;
        }
    }

    //---------------------GET NAME------------------------------
    if( majorTokens[8].contains("RepID=") )
    {
        QRegExp rx("RepID=[^(]*");//Note=any num characters then n=
        int pos = rx.indexIn( majorTokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {
            name = list[i].remove("RepID=").remove(" ");//.remove("(");
            //qDebug() << "------name    " << name << endl;
        }
    }

    //---------------------GET HIT DATA------------------------------
    //get perc_qry_cvrg
    if( majorTokens[8].contains("/%qry_cvrg=") )
    {
        QRegExp rx("/%qry_cvrg=[0-9]{1,3}");//Note=any num characters then n=
        int pos = rx.indexIn( majorTokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {
            //perc_qry_cvrg = (list[i].remove("/%qry_cvrg=")).toInt();//.remove("(");
            QString perc_qry_cvrg_str = (list[i].remove("/%qry_cvrg=").remove(" "));//.toInt();//.remove("(");
            perc_qry_cvrg = perc_qry_cvrg_str.toInt();
            //qDebug() << "------perc_qry_cvrg    " << perc_qry_cvrg << endl; //<< list[i] << endl;//
        }
    }

    //get perc_hit_cvrg
    if( majorTokens[8].contains("/%hit_cvrg=") )
    {
        QRegExp rx("/%hit_cvrg=[0-9]{1,3}");//Note=any num characters then n=
        int pos = rx.indexIn( majorTokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {
            //perc_qry_cvrg = (list[i].remove("/%qry_cvrg=")).toInt();//.remove("(");
            QString perc_hit_cvrg_str = (list[i].remove("/%hit_cvrg=").remove(" "));//.toInt();//.remove("(");
            perc_hit_cvrg = perc_hit_cvrg_str.toInt();
            //qDebug() << "------perc_hit_cvrg    " << perc_hit_cvrg << endl; //<< list[i] << endl;//
        }
    }

    //get perc_ident
    if( majorTokens[8].contains("/%ident=") )
    {
        QRegExp rx("/%ident=[0-9]{1,3}");//Note=any num characters then n=
        int pos = rx.indexIn( majorTokens[8]);
        QStringList list = rx.capturedTexts();
        for(int i = 0; i < list.size(); i++)
        {
            //perc_qry_cvrg = (list[i].remove("/%qry_cvrg=")).toInt();//.remove("(");
            QString perc_ident_str = (list[i].remove("/%ident=").remove(" "));//.toInt();//.remove("(");
            perc_ident = perc_ident_str.toInt();
            //qDebug() << "------perc_ident    " << perc_ident << endl; //<< list[i] << endl;//
        }
    }

    //get exp
//    if( majorTokens[8].contains("/exp=") )
//    {
//        QRegExp rx("/exp=[^//]* ");//Note=any num characters then n=
//        int pos = rx.indexIn( majorTokens[8]);
//        QStringList list = rx.capturedTexts();
//        for(int i = 0; i < list.size(); i++)
//        {
//            exp = (list[i].remove("/exp=").remove(" "));//.toInt();//.remove("(");
//            //qDebug() << "------exp    " << exp << endl; //<< list[i] << endl;//
//        }
//    }


}

